using System;
using System.Collections.Generic;
using System.Linq;
using Picnic.Spec.Exceptions;

namespace Picnic.Spec
{
	public static class AssertExtensions
	{
		#region Action extensions
		
		public static void ShouldRaise<T>(this Action action) where T : Exception
		{
			Exception raisedException = null;
			try
			{
				action();
			}
			catch (Exception exception)
			{
				var requiredException = exception as T;
				if (requiredException != null)
				{
					return;
				}
				raisedException = exception;
			}
			if (raisedException == null)
			{
				throw new RequiredExceptionIsNotThrownException(typeof(T));
			}
			throw new RequiredExceptionIsNotThrownException(typeof(T), raisedException);
		}

		#endregion

		#region Object extensions

		public static void ShouldEquals(this object value, object requiredValue)
		{
			if (!Equals(value, requiredValue))
			{
				throw new EqualsException(requiredValue, value);
			}
		}

		public static void ShouldBeNull(this object value)
		{
			if (value != null)
			{
				throw new EqualsException(null, value);
			}
		}

		#endregion

		#region Boolean extensions

		public static void ShouldBeTrue(this bool value)
		{
			value.ShouldEquals(true);
		}

		#endregion

		#region IEnumerable extensions

		public static void ShouldContains<T>(this IEnumerable<T> collection, T value)
		{
			if (collection == null)
			{
				return;
			}
			collection.Contains(value).ShouldBeTrue();
		}

		#endregion
	}
}